﻿////////////////////////////////////////////////////
//Jiping
//Menu and SubMenu (just simply call registerMenuEvent() for the page where you have menu and subMenu)
//support multiple pairs of menu and submenu by manageing menuIDs, subMenuIDs, and events in array
////////////////////////////////////////////////////

var menuManager = new MenuManager();

//required: menuID, subMenuID
//optional: fakeMenuID, beforeShowSubMenuEventHandler, resigerSubMenuEventHandler
//fakeMenuID: the submenu show under the elemetn with fakeMenuID if it's specified, 
//            but the toggle event is still triggered by clicking element with menuID
//align: 'left' or 'right'
function registerMenuEvent(menuID, subMenuID, options) {
    if ($("#" + menuID).length > 0 && $("#" + subMenuID).length > 0) {
        var menu = new Menu(menuID, subMenuID, options);
        menuManager.addMenu(menu);
        activateMenu();
    }
}

function activateMenu() {
    $(document).click(function (event) {
        for (var i = 0; i < menuManager.menuList.length; i++) {
            var menu = menuManager.menuList[i];
            var smid = "#" + menu.subMenuID;
            if ($(event.target).parents().index($(smid)) == -1) {
                if ($(smid).is(":visible")) {
                    menu.hideSubMenu();
                }
            }
        }
    });

    $(window).resize(function (event) {
        for (var i = 0; i < menuManager.menuList.length; i++) {
            var menu = menuManager.menuList[i];
            menu.keepSubMenu();
        }
        return false;
    });

    for (var i = 0; i < menuManager.menuList.length; i++) {
        var menu = menuManager.menuList[i];
        if (!menu.activated) {
            var mid = "#" + menu.menuID;
            $(mid).click(function (event) {
                menuManager.hideOtherSubMenus(menu);
                menu.toggleSubMenu();
                return false;
            });

            $(mid).mouseover(function (event) {
                if (menu.subMenuIsHidden) {
                    var func = menu.mouseOver;
                    if (func != undefined && func != "undefined") {
                        func(this);
                    }
                }
            })

            $(mid).mouseout(function (event) {
                if (menu.subMenuIsHidden()) {
                    var func = menu.mouseOut;
                    if (func != undefined && func != "undefined") {
                        func(this);
                    }
                }
            })

            //if any actions or events would happen in the submenu, you can pass in the register function (not event handler directly)
            if (menu.subMenuEventHandler != undefined && menu.subMenuEventHandler != "undefined") {
                menu.subMenuEventHandler(menu);
            }
            menu.activated = true;
        }
    }
}

function MenuManager() {

    this.menuList = [];

    this.addMenu = function (menu) {
        var found = 0;
        for (var i = 0; i < this.menuList.length; i++) {
            if (menu.menuID == this.menuList[i].menuID && menu.subMenuID == this.menuList[i].subMenuID) {
                found = 1;
                break;
            }
        }
        if (found == 0) {
            this.menuList[this.menuList.length] = menu;
        }
    }

    this.hideOtherSubMenus = function(menu) {
        for (var i = 0; i < this.menuList.length; i++) {
            if (menu.menuID == this.menuList[i].menuID && menu.subMenuID == this.menuList[i].subMenuID) {
                continue;
            }
            else {
                this.menuList[i].hideSubMenu();
            }
        }
    }

    
}

function Menu(menuID, subMenuID, options) {
    var options_default = {
        'fakeMenuID': null,
        'align': "left",
        'mouseOver': null,
        'mouseOut': null,
        'beforeShow': null,
        'afterHide': null,
        'subMenuEventHandler': null
    }
    for (var name in options_default) {
        if (typeof options[name] == "undefined") {
            this[name] = options_default[name];
        }
        else {
            this[name] = options[name];
        }
    }
    this.activated = false;
    this.menuID = menuID;
    this.subMenuID = subMenuID;

    this.subMenuIsHidden = function () {
        var smid = "#" + this.subMenuID;
        if ($(smid).css("display") == "block" || $(smid).css("display") == "inline") {
            return false;
        }
        else {
            return true;
        }
    }

    this.toggleSubMenu = function () {
        var smid = "#" + this.subMenuID;
        if ($(smid).css("display") == "block" || $(smid).css("display") == "inline") {
            this.hideSubMenu();
        }
        else {
            this.moveSubMenu();
            //execute before showing submenu event
            var func = this.beforeShow;
            if (func != undefined && func != "undefined") {
                func(this);
            }
            //show submenu
            this.showSubMenu();
        }
        return false;
    }

    this.keepSubMenu = function () {
        var smid = "#" + this.subMenuID;
        if ($(smid).css("display") == "block" || $(smid).css("display") == "inline") {
            this.moveSubMenu();
        }
    }

    this.moveSubMenu = function () {
        var mid = "#" + this.menuID;
        if (this.fakeMenuID != undefined && this.fakeMenuID != "undefined") {
            mid = "#" + this.fakeMenuID;
        }
        var smid = "#" + this.subMenuID;
        var mheight = $(mid).height();
        var moffset = $(mid).position();

        var newtop = moffset.top + mheight;
        var newleft = moffset.left;

        //reset top, left/right
        if (this.align != undefined && this.align != "undefined" && this.align == "right") {
            var mwidth = $(mid).width();
            var offsetp = $(mid).offsetParent(); //real offset parent object
            var mparentWidth = offsetp.width();
            //if has horizontal scroll bar, use window width
            var documentwidth = $(document).width();
            var windowwidth = $(window).width();

            var newright = mparentWidth - mwidth - moffset.left;
            //if the offsetParent's position is absolute, relative, or fixed, just use mparentWidth, 
            //but if the offsetParent's position is static (default), and has  horizontal scroll bar, use window with
            if (windowwidth < documentwidth && offsetp.css("position") == "static") {
                newright = windowwidth - mwidth - moffset.left;
            }
            $(smid).css("top", newtop);
            $(smid).css("right", newright);
        }
        else {
            $(smid).css("top", newtop);
            $(smid).css("left", newleft);
        }
    }

    this.hideSubMenu = function () {
        var smid = "#" + this.subMenuID;
        var obj = $(smid);
        if (obj.length > 0) {
            obj.hide();
        }
        var func = this.afterHide;
        if (func != undefined && func != "undefined") {
            func(this);
        }
    }

    this.showSubMenu = function () {
        var smid = "#" + this.subMenuID;
        var obj = $(smid);
        if (obj.length > 0) {
            obj.show();
        }
    }
}